# photo name correction 
# 2021.04 @Wendell
# 需求：修改文件名为拍摄日期，比如：IMG_20210422_070707.jpg

import os
import piexif
import time

def checkFormat(photoPwd):
    '''
    检查文件类型是否为图片格式
    '''
    (root, ext) = os.path.splitext(photoPwd)
    return str.upper(ext[1:]) # 返回文件后缀类型

def checkExif(photoPwd):
    '''
    检查Exif是否包含拍摄日期
    '''
    try:
        exif_dict = piexif.load(photoPwd) # 照片的Exif
        exif_time = piexif.ExifIFD.DateTimeOriginal # 时间在exif_dict里面的key
        return exif_time in exif_dict["Exif"] 
    except Exception as e:
        return False
def getTime1(photoPwd):
    '''
    提取照片拍摄时间
    from '2021:04:22 07:07:07' to '20210422_070707'
    '''
    exif_dict = piexif.load(photoPwd) # 照片的Exif
    exif_time = piexif.ExifIFD.DateTimeOriginal # 时间在exif_dict里面的key
    photoTime = exif_dict["Exif"][exif_time] # byte形式：b'2021:04:22 07:07:07'
    pT = bytes.decode(photoTime) # 转换为str
    photoTime = f'{pT[0:4]}{pT[5:7]}{pT[8:10]}_{pT[11:13]}{pT[14:16]}{pT[17:19]}' # 格式为20210422_070707
    return photoTime

def getTime2(photoName):
    '''
    根据文件名特征提取照片拍摄日期，转换为Exif时间格式
    from 'IMG_20210422_075810.jpg' to '2024:04:22 07:58:10'
    '''
    pN = photoName
    # from IMG_20210422_075810.jpg to 2024:04:22 07:58:10
    imgTime = f'{pN[4:8]}:{pN[8:10]}:{pN[10:12]} {pN[13:15]}:{pN[15:17]}:{pN[17:19]}'
    return imgTime
def getNewName(photoTime):
    '''
    获取照片新文件名，另外，如果两张照片时分秒也相同，在文件名后累加数字123...区分
    '''
    count = 1
    new_photoName = f'IMG_{photoTime}.jpg' # e.g., IMG_20210422_070707.jpg
    while new_photoName in os.listdir(folder):
        new_photoName = f'IMG_{photoTime}_{count}.jpg' # e.g., IMG_20210422_070707_X.jpg
        count += 1        
    return new_photoName

def setName(photoPwd) :
    '''
    根据拍摄日期重命名照片
    e.g., IMG_20210424_071829.jpg
    '''
    photoTime = getTime1(photoPwd)
    new_photoName = getNewName(photoTime) #获取新文件名，如果两张照片时分秒也相同，在最后增加后缀
    new_photoPwd = os.path.join(folder, new_photoName)
    os.rename(photoPwd, new_photoPwd)
    print(new_photoName)
#给其他类型的文件改名
def setNotherName(photoPwd):
    kzm = checkFormat(photoPwd).upper()
    mytime = os.path.getmtime(folder)
    name = time.strftime("%Y%m%d_%H%M%S", time.localtime(mytime))
    new_photoName = f'{kzm}_{name}.{kzm}' # e.g., IMG_20210422_070707.jpg
    new_photoPwd = os.path.join(folder, new_photoName)
    if os.path.exists(photoPwd):
        time.sleep(1)
        kzm = checkFormat(photoPwd).upper()
        mytime = os.path.getmtime(folder)
        name = time.strftime("%Y%m%d_%H%M%S", time.localtime(mytime))
        new_photoName = f'{kzm}_{name}.{kzm}' # e.g., IMG_20210422_070707.jpg
        new_photoPwd = os.path.join(folder, new_photoName)    
    os.rename(photoPwd, new_photoPwd)
    print(new_photoPwd)
def setDate(photoName, photoPwd):
    '''
    给没有时间的照片加上时间
    '''
    imgTime = getTime2(photoName)
    # 设置Exif信息
    exif_dict = piexif.load(photoPwd) # 读取现有Exif信息
    exif_dict['0th'][piexif.ImageIFD.DateTime] = imgTime # 注意DateTime在ImageIFD里面
    exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = imgTime
    exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = imgTime
    exif_bytes = piexif.dump(exif_dict)
    # 插入Exif信息
    piexif.insert(exif_bytes, photoPwd)


def changePhotoTime(photoName):
    """
    修改该路径下的所有JPG照片的时间
    """
    photoPwd = os.path.join(folder, photoName) # 照片的绝对路径
    if checkFormat(photoPwd) == 'JPG': # 如果是JPG
        setDate(photoName, photoPwd)  

def changePhotoName(photoName):
    """
    修改JPG照片的文件名为拍摄日期
    e.g., IMG_20210424_071829.jpg
    """
    photoPwd = os.path.join(folder, photoName) # 照片的绝对路径
    if checkFormat(photoPwd) == 'JPG' and checkExif(photoPwd): # 如果是JPG并且Exif包含时间信息
        setName(photoPwd)


#遍历文件文件夹
def traverse(root_path):
    dir_or_files = os.listdir(root_path)
    for dir_file in dir_or_files:
        #获取目录或者文件的路径
        dir_file_path = os.path.join(root_path,dir_file)
        #判断该路径为文件还是路径
        if os.path.isdir(dir_file_path):
            #递归获取所有文件和目录的路径
            traverse(dir_file_path)
        else:
            path = dir_file_path[:dir_file_path.rfind("/")]
            photoName = dir_file_path[dir_file_path.rfind("/") + 1:]
            global folder
            folder = path                
            if checkFormat(dir_file_path).upper() == 'JPG' and checkExif(dir_file_path) == True: # 如果是JPG并且Exif包含时间信息
                print(dir_file_path)                                                             
                changePhotoName(photoName)
            elif checkFormat(dir_file_path).upper() == 'MP4' or checkFormat(dir_file_path).upper() == 'JPG':
                print(dir_file_path)                                                           
                setNotherName(dir_file_path)
            elif checkExif(dir_file_path) == False:
                if dir_file_path.find("/111") == -1:
                    if os.path.exists(path+"/111") == False:
                        os.mkdir(path+"/111")
                    os.rename(dir_file_path,path+"/111/"+photoName)
                    print("没有拍摄时间信息")
            
#遍历文件文件夹
def traverse1(root_path):
    dir_or_files = os.listdir(root_path)
    for dir_file in dir_or_files:
        #获取目录或者文件的路径
        dir_file_path = os.path.join(root_path,dir_file)
        #判断该路径为文件还是路径
        if os.path.isdir(dir_file_path):
            #递归获取所有文件和目录的路径
            traverse1(dir_file_path)
        else:
            with open(dir_file_path, 'r') as f:
                text = f.read()  
            if text.find("getSmsCode") >= 0:
                print(dir_file_path)  
folder = r"/sdcard/Pictures/WeiXin" #文件夹路径
#folder = r"/sdcard/AppProjects/XposedSmsCode/app/src/main/java/com/tianma/xsmscode"
if __name__ == '__main__':
    '''
    folder: 文件夹路径
    '''
    traverse(folder)

